package com.mbyte.easy.rest.score;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mbyte.easy.admin.entity.Exam;
import com.mbyte.easy.admin.entity.ScoreInfo;
import com.mbyte.easy.admin.enums.DimensionEnums;
import com.mbyte.easy.admin.service.IExamService;
import com.mbyte.easy.admin.service.IScoreInfoService;
import com.mbyte.easy.rest.dto.AnalysisDTO;
import com.mbyte.easy.rest.dto.AnalysisResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.mbyte.easy.admin.enums.DimensionEnums.CHINESE;

/**
 * @author driver-design
 * @description 数据分析
 * @date 2022/4/3
 */
@Slf4j
@RestController
@RequestMapping("/rest/data/analysis")
public class AnalysisRestController {

    @Resource
    private IScoreInfoService scoreInfoService;

    @Resource
    private IExamService examService;

    @PostMapping("/student")
    public JSONObject studentAnalysis(@RequestBody AnalysisDTO analysisDTO){
        JSONObject jsonObject = new JSONObject();
        log.info("dto res :{}", JSON.toJSONString(analysisDTO));

        List<AnalysisResultDTO> analysisResultDTOS = new ArrayList<>();

        // 获取维度
        String dimension = analysisDTO.getDimension();

        // 考试场次
        List<String> examList = analysisDTO.getExamList();
        List<Long> examIds = examList.stream().map(Long::parseLong).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(examIds)) {
            return null;
        }

        // 学生姓名列表
        Set<String> studentNameSet = new HashSet(Arrays.asList(analysisDTO.getNameList().split(",")));
        if (CollectionUtils.isEmpty(studentNameSet)) {
            return null;
        }


        Map<String, List<ScoreInfo>> scoreInfoMap = scoreInfoService.list(new LambdaQueryWrapper<ScoreInfo>()
                        .in(ScoreInfo::getExamId, examIds)
                        .in(ScoreInfo::getName, studentNameSet)
                        .orderByAsc(ScoreInfo::getExamId)
                ).stream().collect(Collectors.groupingBy(ScoreInfo::getName));

        for (String name : studentNameSet) {
            List<ScoreInfo> scoreInfos = scoreInfoMap.get(name);
            List<Integer> scores = new ArrayList<>();
            for (ScoreInfo scoreInfo : scoreInfos) {
                Integer score = getScore(scoreInfo, dimension);
                scores.add(score);
            }
            AnalysisResultDTO analysisResultDTO = new AnalysisResultDTO();
            analysisResultDTO.setData(scores);
            analysisResultDTO.setStack(name);
            analysisResultDTO.setName(name);
            analysisResultDTOS.add(analysisResultDTO);
        }

        // 按序获取场次
        List<String> examNameList = examService.list(new LambdaQueryWrapper<Exam>()
                .in(Exam::getId, examIds)
                .orderByAsc(Exam::getId)
            ).stream().map(Exam::getExamName).collect(Collectors.toList());


        jsonObject.put("examNameList", examNameList);
        jsonObject.put("nameList", studentNameSet);
        jsonObject.put("title", DimensionEnums.of(dimension).getDesc());
        jsonObject.put("scoreResult", analysisResultDTOS);


        return jsonObject;
    }


    private Integer getScore(ScoreInfo scoreInfo, String dimension){
        Integer score = 0;

        switch (dimension) {
            case "chinese":
                score = Integer.parseInt(scoreInfo.getChinese());
                break;
            case "math":
                score = Integer.parseInt(scoreInfo.getMath());
                break;
            case "english":
                score = Integer.parseInt(scoreInfo.getEnglish());
                break;
            case "wen_sum":
                score = Integer.parseInt(scoreInfo.getWenSum());
                break;
            case "li_sum":
                score = Integer.parseInt(scoreInfo.getLiSum());
                break;
            case "score_sum":
                score = Integer.parseInt(scoreInfo.getScoreSum());
                break;
            case "grade_rank":
                score = scoreInfo.getGradeRank();
                break;
            case "school_rank":
                score = scoreInfo.getSchoolRank();
                break;
            default:
                break;
        }

        return score;
    }

}
